home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
exampleCode
/
opengl
/
motif
/
xmblur.c
< prev
Wrap
C/C++ Source or Header
|
1996-11-11
|
9KB
|
305 lines
/*
* Copyright (c) 1994, Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that the name of Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE
* POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
/* $Revision: 1.2 $ */
/* compile: cc -o xmblur xmblur.c -lGLw -lGLU -lGL -lXm -lXt -lX11 */
#include <stdlib.h>
#include <stdio.h>
#include <Xm/Form.h>
#include <Xm/Frame.h>
#include <GL/GLwMDrawA.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glx.h>
static int snglBuf[] =
{
GLX_RGBA,
GLX_ACCUM_RED_SIZE, 8,
GLX_ACCUM_GREEN_SIZE, 8,
GLX_ACCUM_BLUE_SIZE, 8,
None
};
static int dblBuf[] =
{
GLX_RGBA,
GLX_DOUBLEBUFFER,
GLX_ACCUM_RED_SIZE, 8,
GLX_ACCUM_GREEN_SIZE, 8,
GLX_ACCUM_BLUE_SIZE, 8,
None
};
static String fallbackResources[] =
{
"*title: OpenGL motion blur demo",
"*glxarea*width: 300", "*glxarea*height: 300",
"*frame*x: 20", "*frame*y: 20",
"*frame*topOffset: 20", "*frame*bottomOffset: 20",
"*frame*rightOffset: 20", "*frame*leftOffset: 20",
"*frame*shadowType: SHADOW_IN",
NULL
};
GLfloat angleX = 15.0, angleY = 12.0;
GLboolean doubleBuffer = GL_TRUE;
Display *dpy;
XtAppContext app;
Widget toplevel, form, frame, glxarea;
XVisualInfo *visinfo;
GLXContext glxcontext;
XFontStruct *xfont;
int firstChar, lastChar;
GLuint fontBase;
char *status;
GLboolean doBlur;
GLUquadricObj *quadObj;
void
setBlur(GLboolean blurMode)
{
doBlur = blurMode;
if (doBlur) {
status = "Blur: enabled";
glClear(GL_ACCUM_BUFFER_BIT); /* blow away accumulation contents */
} else {
status = "Blur: disabled";
}
}
void
drawScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);
/*
* Draw the wireframe cylinder.
*/
glColor3f(1.0, 0.0, 0.0);
glPushMatrix();
glRotatef(angleX, 1.0, 0.0, 0.0);
glRotatef(angleY, 0.0, 1.0, 0.0);
glCallList(1);
glPopMatrix();
/*
* Use accumulation buffer for motion blurring.
*/
if (doBlur) {
/*
* Be careful not to overflow the accumulation buffer; GL_RETURN is
* the only accumulation buffer operation defined to do clamping.
* Don't assume GL_MULT or GL_ACCUM clamp.
*/
glAccum(GL_MULT, 0.8);
glAccum(GL_ACCUM, 0.2);
/*
* Renormalize the return by multipling the accumulation buffer
* contents by 5.
*/
glAccum(GL_RETURN, 5.0);
}
/*
* Print out instructions and blur mode.
*/
#define HELP1 "Push 's' to step frame"
#define HELP2 "Push 'b' toggles blur"
glColor3f(1.0, 1.0, 0.0);
glRasterPos2i(-14, 13);
glCallLists(sizeof(HELP1) - 1, GL_UNSIGNED_BYTE, HELP1);
glColor3f(1.0, 1.0, 0.0);
glRasterPos2i(-14, 11);
glCallLists(sizeof(HELP2) - 1, GL_UNSIGNED_BYTE, HELP2);
glColor3f(0.0, 1.0, 0.0);
glRasterPos2i(-14, -14);
glCallLists(strlen(status), GL_UNSIGNED_BYTE, (unsigned char *) status);
/*
* Swap the buffer if we are double buffering.
*/
if (doubleBuffer)
GLwDrawingAreaSwapBuffers(glxarea);
/*
* Finish to ensure we aren't buffering up too much work.
*/
glFinish();
}
void
input_callback(Widget w, XtPointer client_data, XtPointer call)
{
char buffer[31];
KeySym keysym;
GLwDrawingAreaCallbackStruct *call_data;
XComposeStatus composeStatus;
call_data = (GLwDrawingAreaCallbackStruct *) call;
switch (call_data->event->type) {
case KeyPress:
XLookupString(&call_data->event->xkey, buffer,
30, &keysym, &composeStatus);
switch (keysym) {
case XK_Escape:
exit(0);
break;
case XK_B:
case XK_b:
setBlur(!doBlur); /* toggle blur mode */
drawScene();
break;
case XK_S:
case XK_s:
angleX += 15.0;
angleY += 12.0;
if (angleX >= 360.0)
angleX = 0.0;
if (angleY >= 360.0)
angleY = 0.0;
drawScene();
break;
}
break;
}
}
void
resize_callback(Widget w, XtPointer client_data, XtPointer call)
{
GLwDrawingAreaCallbackStruct *call_data;
call_data = (GLwDrawingAreaCallbackStruct *) call;
glViewport(0, 0, call_data->width, call_data->height);
}
void
expose_callback(Widget w, XtPointer client_data, XtPointer call)
{
GLwDrawingAreaCallbackStruct *call_data;
call_data = (GLwDrawingAreaCallbackStruct *) call;
if (doBlur) {
/*
* Can't trust the contents of the accumulation buffer after
* an expose. Note: this makes xmblur regenerate itself after
* an expose properly if blur is enabled.
*/
glClear(GL_ACCUM_BUFFER_BIT);
}
drawScene();
}
void
init_callback(Widget w, XtPointer client_data, XtPointer call)
{
XVisualInfo *visinfo;
XtVaGetValues(w, GLwNvisualInfo, &visinfo, NULL);
glxcontext = glXCreateContext(XtDisplay(w), visinfo,
/* no sharing */ 0, /* direct if possible */ GL_TRUE);
}
main(int argc, char **argv)
{
toplevel = XtAppInitialize(&app, "Glxwidget", NULL, 0, &argc, argv,
fallbackResources, NULL, 0);
dpy = XtDisplay(toplevel);
form = XmCreateForm(toplevel, "form", NULL, 0);
XtManageChild(form);
frame = XmCreateFrame(form, "frame", NULL, 0);
XtVaSetValues(frame, XmNbottomAttachment, XmATTACH_FORM,
XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM, NULL);
XtManageChild(frame);
/*
* We find the XVisualInfo* we want for the GLwMDrawA widget _before_ we
* create the widget. The alternative to this is specifying the OpenGL
* visual attributes as resources arguments when creating the widget but
* unfortunately, if a visual matching the attributes we specify does not
* exist, we get a fatal error message like:
*
* Error: GLwMDrawingArea: requested visual not supported
*
* By specifying exactly which XVisualInfo* we want, we avoid this problem,
* allowing us to fall back to another acceptable set of visual
* attirbutes (single buffered in this case) and print out our own more
* informative message if even the second visual selection fails.
*/
visinfo = glXChooseVisual(dpy, DefaultScreen(dpy), dblBuf);
if (visinfo == NULL) {
visinfo = glXChooseVisual(dpy, DefaultScreen(dpy), snglBuf);
if (visinfo == NULL)
XtAppError(app, "no RGB visual with accumulation buffer");
doubleBuffer = GL_FALSE;
}
/*
* Load the desired font.
*/
xfont = XLoadQueryFont(dpy, "9x15");
if (xfont == NULL) {
XtAppError(app, "no 9x15 font found");
}
glxarea = XtVaCreateManagedWidget("glxarea", glwMDrawingAreaWidgetClass,
frame, GLwNvisualInfo, visinfo, NULL);
XtAddCallback(glxarea, GLwNginitCallback, init_callback, NULL);
XtAddCallback(glxarea, GLwNexposeCallback, expose_callback, NULL);
XtAddCallback(glxarea, GLwNresizeCallback, resize_callback, NULL);
XtAddCallback(glxarea, GLwNinputCallback, input_callback, NULL);
XtRealizeWidget(toplevel);
GLwDrawingAreaMakeCurrent(glxarea, glxcontext);
/*
* Make cylinder display list.
*/
quadObj = gluNewQuadric();
gluQuadricDrawStyle(quadObj, GLU_LINE);
glNewList(1, GL_COMPILE);
gluCylinder(quadObj, 2.0, 5.0, 10.0, 10, 4);
glEndList();
/*
* Now the GLwNginitCallback has been called so the OpenGL context has
* been set up. Now we can initialize the X font as a set of OpenGL
* display lists.
*/
firstChar = xfont->min_char_or_byte2;
lastChar = xfont->max_char_or_byte2;
glXUseXFont(xfont->fid, firstChar, lastChar - firstChar + 1,
/* base display list of glyphs */ 2
/* since 1 is used for the cylinder */);
glListBase(2 - firstChar);
/*
* Initialize OpenGL state.
*/
glViewport(0, 0, 300, 300); /* XXX work around Reality Engine bug */
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearAccum(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-15.0, 15.0, -15.0, 15.0, -15.0, 15.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
setBlur(GL_FALSE);
/*
* Start dispatching X events...
*/
XtAppMainLoop(app);
}